﻿\subsection{中断和异常的分类}

x86 CPU 上电后就一直从 \lstinline{CS:EIP} 指示的指令地址从内存中取出程序指令并解释执行。
中断（Interupt）和异常（Exception）是指在 CPU 运行过程中由于特定事件发生而导致的 CPU 程序执行流的改变。
中断或异常发生后，CPU 暂停执行当前程序，转而执行一段被称作中断例程（Interupt Routine）的程序。

x86 体系结构中，中断可根据触发事件的不同分为三类：外中断（External Interupts）、不可屏蔽中断（Non-Maskable Interupts，NMI）、内中断（Internal Interupts）。

在 x86 CPU 上提供了两根中断引脚 INTR 及 NMI，用于接收外部信号。
从 INTR 引脚传入的中断信号被称为外部中断信号，如时钟中断就是典型的外部中断信号。
CPU 可通过设置 \lstinline{EFLAGS.IF} 决定是否受理外部中断事件。
在设计引导加载器时，就曾使用过 \lstinline{cli} 指令屏蔽外部中断，因此，自 INTR 引脚传入信号触发的中断又称作可屏蔽中断（Maskable Interupts）。

对应地，从 NMI 引脚传入不可屏蔽中断信号，由这种信号触发的中断被称作不可屏蔽中断，不可屏蔽中断由硬件一级直接处理，不能被中断标志位屏蔽。

内中断则由程序员在编写程序时通过 \lstinline{int} 指令故意触发，又被称作软件中断（Software-Generated Interupts）。
不同于外中断和不可屏蔽中断，内中断的中断源就是 CPU 解释执行的指令本身，即中断源位于 CPU 内部。

异常与内中断类似，也发生在 CPU 内部，CPU 执行某条指令时发现存在异常情况时将触发异常，如：除法指令除数为 0、访问内存发生缺页等。
根据异常严重级别不同，异常可进一步细分为故障（Fault）、陷阱（Trap）、中止（Abort）。
故障通常可被纠正，如缺页故障（Page Fault）。
陷阱通常用于程序调试，如使用 LLVM-Clang 以 \lstinline{-g} 选项编译程序后，在反汇编的代码中可见到数条陷阱指令 \lstinline{int3}。

在 CPU 报告中断或异常事件时，对于内外中断和一般异常（故障、陷阱），其报告精度（Precision）是可预见的，即可以确定中断或异常的指令边界（Instruction Boundary），
进而可在正确处理中断或异常的基础上，恢复指令的执行。例如缺页故障发生时，CPU 会将当前执行流的状态恢复到执行访存指令之前，正确处理缺页故障后，触发缺页的访存指令可照常执行。
而中止事件的报告精度无法保证，当中止发生后，程序一般无法继续运行。\cite{amd64}
